﻿using System;
using System.Globalization;
using System.Threading.Tasks;
using Casamiel.API.Application;
using Casamiel.API.Application.Commands;
using Casamiel.API.Application.Services;
using Casamiel.API.Infrastructure;
using Casamiel.API.Infrastructure.Filters;
using Casamiel.API.Infrastructure.Middlewares;
using Casamiel.Application;
using Casamiel.Application.Commands;
using Casamiel.Common;
using Casamiel.Domain;
using Casamiel.Domain.Entity;
using MediatR;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Newtonsoft.Json.Linq;

// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860

namespace Casamiel.API.Controllers.V2
{
    /// <summary>
    /// Employee controller.
    /// </summary>
    [Produces("application/json")]
    [ApiVersion("2.0")]
    [Route("api/v{api-version:apiVersion}/[controller]")]
    [EnableCors("any")]
    [ApiController]
    public class EmployeeController : Controller
    {
        private readonly string _imgUrl = "";
        // private readonly NLog.ILogger logger = LogManager.GetLogger("EmployeeService");
        private readonly IIcApiService _icApiService;
        private readonly IEmployeeService _employeeService;
        private readonly IMemberService _memberService;
        private readonly IUserLogService _userLog;
        private readonly ICacheService _cacheService;
        private readonly IMobileCheckCode _mobileCheckCode;
        private readonly ITokenProvider _tokenProvider;
        private readonly IMediator _mediator;
        /// <summary>
        /// Initializes a new instance of the <see cref="T:Casamiel.API.Controllers.V2.EmployeeController"/> class.
        /// </summary>
        /// <param name="employeeService">Employee service.</param>
        /// <param name="memberService">Member service.</param>
        /// <param name="userLog">User log.</param>
        /// <param name="cacheService">Cache service.</param>
        /// <param name="mobileCheckCode">Mobile check code.</param>
        /// <param name="iicApiService">Iic API service.</param>
        /// <param name="settings"></param>
        /// <param name="tokenProvider"></param>
		/// <param name="mediator"></param>
        public EmployeeController(IEmployeeService employeeService, IMemberService memberService, IUserLogService userLog, ICacheService cacheService,
                                  IMobileCheckCode mobileCheckCode, IIcApiService iicApiService, IOptionsSnapshot<IcServiceSettings> settings, ITokenProvider tokenProvider, IMediator mediator)
        {
            if (settings == null) {
                throw new ArgumentNullException(nameof(settings));
            }

            _employeeService = employeeService;
            _memberService = memberService;
            _userLog = userLog;
            _cacheService = cacheService;
            _mobileCheckCode = mobileCheckCode;
            _icApiService = iicApiService;
            _imgUrl = settings.Value.appUrls[0].Url;
            _tokenProvider = tokenProvider;
            _mediator = mediator;
        }
        /// <summary>
        /// Gets the test.
        /// </summary>
        /// <returns>The test.</returns>
        /// <param name="mobile">Mobile.</param>
        [HttpPost]
        [Route("[action]")]
        public async Task<IActionResult> GetTest(string mobile)
        {
            var entity = await _employeeService.FindAsync<ICasaMielSession>(mobile).ConfigureAwait(false);
            return Ok(entity);
        }

        /// <summary>
        /// Gets the login check code.
        /// </summary>
        /// <returns>The login check code.</returns>
        /// <param name="data">Data.</param>
        /// <remarks>{"mobile":"13588888888"}</remarks>
        [HttpPost]
        [Route("[action]")]
        public async Task<IActionResult> GetCheckCode([FromBody] JObject data)
        {
            if (data == null) {
                throw new ArgumentNullException(nameof(data));
            }

            if (string.IsNullOrEmpty(data["mobile"].ToString())) {
                return new JsonResult(new { code = -5, msg = "手机号不能为空" });
            }
            string mobile = data["mobile"].ToString();
            if (string.IsNullOrEmpty(mobile)) {
                return new JsonResult(new { code = -5, msg = "手机号不能为空" });
            }

            var msg = await _mobileCheckCode.SendCheckCodeAsync(mobile).ConfigureAwait(false);
            if (string.IsNullOrEmpty(msg)) {
                return new JsonResult(new { code = 0, msg = "验证码已发送" });
            }
            return new JsonResult(new { code = -6, msg = "验证码发送失败" });
        }

        /// <summary>
        /// Login the specified data.
        /// </summary>
        /// <returns>The login.</returns>
        /// <param name="data">Data.</param>
        /// <remarks>{"mobile":"","yzm":"8888"}</remarks>
        [HttpPost]
        [HttpOptions]
        [Route("[action]")]
        public async Task<IActionResult> Login([FromBody]JObject data)
        {
            if (data == null) {
                throw new ArgumentNullException(nameof(data));
            }

            string mobile = data["mobile"].ToString();

            var entity = await _employeeService.FindAsync<ICasaMielSession>(data["mobile"].ToString()).ConfigureAwait(false);
            if (entity == null) {
                return new JsonResult(new { code = "-2", msg = "用户不存在" });
            }

            //if (data["yzm"].ToString() != "0000") {
            var sucess = _mobileCheckCode.CheckCode(mobile, data["yzm"].ToString(), true);

            if (sucess["Success"].ToString().ToLower(CultureInfo.CurrentCulture) == "false") {
                return new JsonResult(new { code = "-2", msg = sucess["msg"].ToString() });
            }
            //}
            //var signingKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("cssupersecret_secretke!miel"));
            //TokenProviderOptions _tokenOptions = new TokenProviderOptions
            //{
            //    Audience = "casamiel",
            //    Issuer = "CasamielIssuer",
            //    SigningCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256)
            //};
            //var tpm = new TokenProvider(_tokenOptions);
            var tokens = _tokenProvider.GenerateToken(data["mobile"].ToString());
            var userAgent = string.IsNullOrEmpty(Request.Headers["User-Agent"].ToString()) ? Request.Headers["UserAgent"].ToString() : Request.Headers["User-Agent"].ToString();
            int loginType = 4;

            var m = await _memberService.FindAsync<ICasaMielSession>(mobile, loginType).ConfigureAwait(false);
            if (m != null) {
                m.Access_Token = tokens.access_token;
                m.UpdateTime = DateTime.Now;
                m.Login_Count++;
                m.Expires_In = tokens.expires_in;
                //m.Resgistration_Id = data.registration_Id;
                await _memberService.UpdateAsync<ICasaMielSession>(m).ConfigureAwait(false);
            } else {
                m = new MemberAccessToken {
                    Access_Token = tokens.access_token,
                    CreateTime = DateTime.Now,
                    UpdateTime = DateTime.Now,
                    Login_Count = 1,
                    Login_Type = loginType,
                    Mobile = mobile,
                    Expires_In = tokens.expires_in
                };
                await _memberService.AddAsync<ICasaMielSession>(m).ConfigureAwait(false);
            }
            var logdata = new UserLog { Url = Request.GetShortUri(), OPInfo = $"销售用户登陆", OPTime = DateTime.Now, UserName = mobile, UserIP = Request.GetUserIp() };
            // await _userLog.AddAsync<ICasaMielSession>(logdata).ConfigureAwait(false);
            await _mediator.Publish(new UserLogNoticeCommand(logdata)).ConfigureAwait(false);
            //string key = Constant.TOKEN_PREFIX + mobile + "_" + loginType;
            //_cacheService.Remove(key);

            return new JsonResult(new { code = 0, data = tokens, member = entity });
        }

        /// <summary>
        /// Logout the specified token.
        /// </summary>
        /// <returns>The logout.</returns>
        /// <param name="token">Token.</param>
        [HttpPost]
        [HttpOptions]
        [Route("[action]")]
        [TypeFilterAttribute(typeof(BookingCheckTokenAttribute))]
        public async Task<IActionResult> Logout([FromHeader(Name = "u-token")] string token)
        {
            //var userAgent = Request.Headers["User-Agent"].ToString() == "" ? Request.Headers["User-Agent"].ToString() : Request.Headers["UserAgent"].ToString();
            int loginType = 4;//userAgent.Contains("CASAMIEL") ? 1 : 2;

            var mobile = MemberHelper.GetMobile(token);
            var logoutcommand = new LogoutCommand(mobile, loginType) { RequestUrl = Request.GetShortUri(), UserIP = Request.GetUserIp() };
            await _mediator.Send(logoutcommand).ConfigureAwait(false);
            //var mobile = MemberHelper.GetMobile(token);
            //var mtoken = await _memberService.FindAsync<ICasaMielSession>(mobile, loginType);
            //if (mtoken != null)
            //{
            //    mtoken.Access_Token = "";
            //    await _memberService.UpdateAsync<ICasaMielSession>(mtoken);
            //}
            //string key = Constant.TOKEN_PREFIX + mobile + "_" + loginType;
            //_cacheService.Remove(key);
            //var logdata = new UserLog { Url = Request.GetAbsoluteUri(), OPInfo = "销售员注销", OPTime = DateTime.Now, UserName = mobile, UserIP = Request.GetUserIp() };
            //await _userLog.AddAsync<ICasaMielSession>(logdata);
            return new JsonResult(new { code = 0, msg = "注销成功！" });
        }
    }
}
